/**axios封装
 * 请求拦截、相应拦截、错误统一处理
 */
import axios from "axios"; // 引入axios
import QS from "qs"; // 引入qs模块，用来序列化post类型的数据
import { Message, Loading } from "element-ui"; // element Toast的提示
// import router from "@/router";
import router from "@/router/routers";
import { getToken, removeToken } from "@/utils/auth";

// import store from "@/store";

// 环境的切换
// if (process.env.NODE_ENV == "development") {
//   axios.defaults.baseURL = "/api";
// } else if (process.env.NODE_ENV == "debug") {
//   axios.defaults.baseURL = "/api";
// } else if (process.env.NODE_ENV == "production") {
//   axios.defaults.baseURL = "/api";
// }

/*
const throwErr = (code, response) => {
  let message = '请求错误'
  switch (code) {
    case 400:
      message = '请求错误'
      break
    case 401:
      message = '未授权，请登录'
      break
    case 403:
      message = '拒绝访问'
      break
    case 404:
      message = `请求地址出错: ${response.config.url}`
      break
    case 408:
      message = '请求超时'
      break
    case 500:
      message = '服务器内部错误'
      break
    case 501:
      message = '服务未实现'
      break
    case 502:
      message = '网关错误'
      break
    case 503:
      message = '服务不可用'
      break
    case 504:
      message = '网关超时'
      break
    case 505:
      message = 'HTTP版本不受支持'
      break
    default:
  }
  return message
}
*/

const api = axios.create({
  paramsSerializer: function(params) {
    return QS.stringify(params, { arrayFormat: "repeat" });
  },
  transformRequest: [
    function(data) {
      // `transformRequest` 允许在向服务器发送前，修改请求数据
      // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
      // data.sex = "man";
      return QS.stringify(data, { arrayFormat: "repeat" });
      // 结合create_headers里的内容，在这里又新增一条信息sex=man
      // 因此network中查看的结果是：name=xiaoming&age=12&sex=man
    }
  ],

  headers: { "Content-Type": "application/x-www-form-urlencoded" }
});
export const baseUrl = process.env.VUE_APP_BASE_URL;
api.defaults.baseURL = baseUrl;
// 请求超时时间
api.defaults.timeout = 10000;

// post请求头
// api.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

// 请求拦截器
api.interceptors.request.use(
  config => {
    // 每次发送请求之前判断是否存在token，如果存在，则统一在http请求的header都加上token，不用每次请求都手动添加了，
    // 即使本地存在token，也有可能token是过期的，所以在响应拦截器中要对返回状态进行判断
    if (getToken()) {
      config.headers["Authorization"] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    // token && (config.headers["x-token"] = token);
    return config;
  },
  error => {
    return Promise.error(error);
  }
);

// 响应拦截器
api.interceptors.response.use(
  response => {
    // debugger;
    // 如果返回的状态码为200，说明接口请求成功，可以正常拿到数据，否则的话抛出错误
    if (response.status === 200) {
      if (response.data && response.data.code === -1) {
        return Promise.reject(response);
      }
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  // 服务器状态码不是200的情况
  // 这里需与后台开发人员协商好统一的错误状态码
  // 然后根据返回的状态码进行一些操作，例如登录过期提示，错误提示等等
  // 下面列举几个常见的操作，其他需求可自行扩展
  error => {
    // debugger;
    if (error.response.status) {
      switch (error.response.status) {
        // 401: 未登录
        // 未登录则跳转登录页面，并携带当前页面的路径
        // 在登录成功后返回当前页面，这一步需要在登录页操作
        case 401:
          Message({
            type: "error",
            message: "登录过期，请重新登录"
          });
          // 清除token
          localStorage.removeItem("token");
          removeToken();
          // store.commit("loginSuccess", null);
          // 跳转登录页面，并将要浏览的页面fullPath传过去，登录成功后跳转需要访问的页面
          setTimeout(() => {
            router.replace({
              path: "/login",
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
          }, 1);

          break;
        // 403 token过期
        // 登录过期对用户进行提示
        // 清除本地token和清空vuex中token对象
        // 跳转登录页面
        case 403:
          Message({
            type: "error",
            message: "登录过期，请重新登录"
          });
          // 清除token
          localStorage.removeItem("token");
          // store.commit("loginSuccess", null);
          // 跳转登录页面，并将要浏览的页面fullPath传过去，登录成功后跳转需要访问的页面
          setTimeout(() => {
            router.replace({
              path: "/auth/login",
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
          }, 1000);
          break;
        // 404请求不存在
        case 404:
          Message({
            type: "error",
            message: "网络请求不存在"
          });
          Loading.service().close();
          break;
        // 500
        case 500:
          Message({
            type: "error",
            message: "服务器内部错误"
          });
          Loading.service().close();
          break;
        // 其他错误，直接抛出错误提示
        default:
          Message({
            type: "error",
            message: error.response.data.message
          });
      }
      return Promise.reject(error.response);
    }
  }
);
/**
 * get方法，对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function get(url, params) {
  return new Promise((resolve, reject) => {
    api
      .get(url, {
        params: params
      })
      .then(res => {
        resolve(res.data);
      })
      .catch(err => {
        reject(err.data);
      });
  });
}
/**
 * post方法，对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function post(url, params) {
  const loading = Loading.service({
    lock: true,
    text: "Loading",
    spinner: "el-icon-loading",
    background: "rgba(0, 0, 0, 0.7)"
  });
  return new Promise((resolve, reject) => {
    api
      .post(url, params)
      .then(res => {
        loading.close();
        resolve(res.data);
        Message.success({
          message: "操作成功",
          type: "success"
        });
      })
      .catch(err => {
        loading.close();
        reject(err.data);
        Message.error({
          message: "操作失败",
          type: "error"
        });
      });
  });
}
/**
 * put方法，对应put请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function put(url, params) {
  const loading = Loading.service({
    lock: true,
    text: "Loading",
    spinner: "el-icon-loading",
    background: "rgba(0, 0, 0, 0.7)"
  });
  return new Promise((resolve, reject) => {
    api
      .put(url, params)
      .then(res => {
        loading.close();
        resolve(res.data);
        Message.success({
          message: "操作成功",
          type: "success"
        });
      })
      .catch(err => {
        loading.close();
        reject(err.data);
        Message.error({
          message: "操作失败",
          type: "error"
        });
      });
  });
}
/**
 * deletee方法，对应deletee请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function deletee(url, params) {
  const loading = Loading.service({
    lock: true,
    text: "Loading",
    spinner: "el-icon-loading",
    background: "rgba(0, 0, 0, 0.7)"
  });
  return new Promise((resolve, reject) => {
    api
      .delete(url, { params: params })
      .then(res => {
        loading.close();
        resolve(res.data);
        Message.success({
          message: "操作成功",
          type: "success"
        });
      })
      .catch(err => {
        loading.close();
        reject(err.data);
        Message.error({
          message: "操作失败",
          type: "error"
        });
      });
  });
}

export function postLogin(url, params) {
  const loading = Loading.service({
    lock: true,
    text: "Loading",
    spinner: "el-icon-loading",
    background: "rgba(0, 0, 0, 0.7)"
  });
  return new Promise((resolve, reject) => {
    api
      .post(url, params)
      .then(res => {
        loading.close();
        resolve(res.data);
      })
      .catch(err => {
        loading.close();
        reject(err.data);
        Message.error({
          message: "登录失败",
          type: "error"
        });
      });
  });
}
